BITS 32
%include "macrosmodoprotegido.mac"

%define esp_anterior [ebp+16]

extern fin_intr_pic1
extern excepciones
extern printf
extern imprimir_todo
extern pagina_libre_usuario
extern mapear_pagina
extern obtener_virtual_libre

global _isr0
global _isr1
global _isr2
global _isr3
global _isr4
global _isr5
global _isr6
global _isr7
global _isr8
global _isr9
global _isr10
global _isr11
global _isr12
global _isr13
global _isr14
global _isr15
global _isr16
global _isr17
global _isr18
global _isr19
global _isr_clock
global _isr_teclado
global _isr88
global _isr89

hexa: dd 0x00000000
offset: dd 0x00000000
selector: dw 0x0000

_isr0:
	enum_isr 0

_isr1:
	enum_isr 1

_isr2:
	enum_isr 2

_isr3:
	enum_isr 3

_isr4:
	enum_isr 4

_isr5:
	enum_isr 5

_isr6:
	enum_isr 6

_isr7:
	enum_isr 7

_isr8:
	enum_isr 8

_isr9:
	enum_isr 9

_isr10:
	enum_isr 10

_isr11:
	enum_isr 11
	
_isr12:
	enum_isr 12
	
_isr13:
	enum_isr 13
	
_isr14:
	enum_isr 14
	
_isr15:
	enum_isr 15
	
_isr16:
	enum_isr 16
	
_isr17:
	enum_isr 17
	
_isr18:
	enum_isr 18
	
_isr19:
	enum_isr 19
	
_isr_clock:
	cli
	pushad
	call fin_intr_pic1
	call proximo_reloj
	str ax
	add ax, 0x8
	cmp ax, 0x58
	jne sigo
	mov ax, 0x38
sigo:
	mov [selector],ax
	jmp far [offset]
	popad
	iret

_isr_teclado:
	cli
	pushad
	xor eax, eax
	mov ax, ds
	push eax
	mov ax, es
	push eax
	mov ax, 0x10
	mov ds, ax
	mov ax, 0x18
	mov es, ax
	; Buscar el scancode, traducirlo y pasarlo por pantalla.
	xor eax, eax
	in al, 0x60				;leer el scancode del teclado.
	call imprimir_teclado	;traducir y pasar por pantalla.
	call fin_intr_pic1
	pop eax
	mov es, ax
	pop eax
	mov ds, ax
	popad
	sti
	iret

_isr88:
	cli
	push ebp
	mov ebp, esp
	pushad
	
	xor eax, eax
	xor esi, esi
	xor edi, edi
	
	mov ax, ds	;guardo ds en di.
	mov di, ax
	mov ax, es	;guardo es en si.
	mov si, ax
	mov ax, 0x10
	mov ds, ax
	mov ax, 0x18
	mov es, ax
	
	;xchg bx,bx
	
	mov eax, esp_anterior
	
	;xchg bx,bx
	
	mov ebx, [eax+20]
	push ebx
	mov ebx, [eax+16]
	push ebx
	mov ebx, [eax+12]
	push ebx
	mov ebx, [eax+8]
	push ebx
	
	call printf
	add esp, 16
	
	mov ax, si	
	mov es, ax
	mov ax, di
	mov ds, ax
	
	popad
	pop ebp
	sti
	iret

_isr89:
	cli
	push ebp
	mov ebp, esp
	
	mov eax, cr3		;guardamos en ebx el dir de paginas de la tarea actual.
	mov ebx, eax
	
	mov eax, 0x100000	;seteamos el directorio de kernel como actual.
	mov cr3, eax	
	
	;unsigned int obtener_virtual_libre(unsigned int *cr3)
	push ebx
	call obtener_virtual_libre
	add esp, 4
	cmp eax, 0
	je error
	mov esi, eax		;tenemos en esi la direccion virtual libre obtenida.
	
	;xchg bx, bx
	
	call pagina_libre_usuario	
	cmp eax, 0
	je error
	mov edi, eax		;tenemos en edi la direccion fisica libre obtenida.	
	
	;void mapear_pagina(unsigned int virtual, unsigned int cr3, unsigned int fisica,unsigned int atributos)
	push dword 7
	push edi
	push ebx
	push esi	
	call mapear_pagina
	add esp, 16
	
	jmp fin
	
error:
	xor esi, esi
fin:
	mov eax, ebx
	mov cr3, eax	;volvemos al directorio de la tarea.
	mov eax, esi
	pop ebp
	sti
	iret
	
	
proximo_reloj:
	pushad
	inc DWORD [isrnumero]
	mov ebx, [isrnumero]
	cmp ebx, 0x4
	jl .ok
		mov DWORD [isrnumero], 0x0
		mov ebx, 0
	.ok:
		add ebx, isrmensaje1
		mov edx, isrmensaje
		IMPRIMIR_TEXTO edx, 6, 0x0A, 24, 73
		IMPRIMIR_TEXTO ebx, 1, 0x0A, 24, 79
	popad
	ret
	
imprimir_teclado:		; mira que tecla se apreto.
	cmp al, 0x02
	jl no_imprimir		; si se apreto otra tecla en vez de un numero no hace nada.
	cmp al, 0x0B
	je es_0
	jg no_imprimir		; si se apreto otra tecla en vez de un numero no hace nada.
	sub al, 1			; llega si esta en el rango de los numeros imprimibles.
	mov ebx, eax
	jmp devolver_num

	es_0:
		xor ebx, ebx
		
	devolver_num:	; escribe el ascii correspondiente y lo pasa por pantalla.
		BYTE_TO_HEX bl, ebx
		lea eax, [ebx+1]
		and byte[eax+1], 0x00	; para indicar el fin del char.
		push 0
		push 24
		push 0x0F
		push eax
		call printf
		add esp, 16
	no_imprimir:
		ret

isrmensaje: db 'Clock:',0
isrnumero: dd 0x00000000
isrmensaje1: db '|'
isrmensaje2: db '/'
isrmensaje3: db '-'
isrmensaje4: db '\'




